<template>
    <section class="chatlist" :class="showSelBox > 0 ? 'chatlist-bottom-collapse' : 'chatlist-bottom'"
        v-water-marker="{ text: '金哥版权所有', textColor: 'rgba(180, 180, 180, 0.4)' }">
        <ul>
            <template v-for="item in records">
                <li class="chat-mine" v-if="item.type == 1">
                    <div class="chat-user"><img src="../assets/user.png"></div>
                    <div class="time"><cite><i>{{ item.time }}</i>{{ item.name }}</cite></div>
                    <div v-copy class="chat-text language-python" v-html="escapeVue(item.content)"></div>
                </li>
                <li v-if="item.type == 2" v-highlight>
                    <div class="chat-user"><img src="../assets/default.png"></div>
                    <div class="time"><cite>{{ item.name }}<i>{{ item.time }}</i></cite></div>
                    <pre class="chat-text"><code v-copy v-html="escapeVue(item.content)" ></code></pre>
                </li>
            </template>
        </ul>
    </section>

    <audio ref="audio" id="audio"></audio>

    <section class="foot">
        <div class="mint-cell-wrapper">
            <div class="mint-cell-value">
                <div style="position: absolute;top: 0;left:0;right:0;bottom: 0;width: 100%;">
                    <div class="con"><input id="txtContent" type="text" placeholder="请输入消息" class="mint-field-core"
                            v-model="content" v-model-save="content" @keydown.enter="s" ref="input" /></div>
                </div>
                <div class="coc mint-field-clear" v-show="content" v-on:click="clearMsg"><i
                        class="fa-sharp fa-solid fa-circle-xmark"></i></div>
                <button class="btn btn-send" v-on:click="s" :disabled="!isSend">&nbsp;&nbsp;发&nbsp;送&nbsp;&nbsp;</button>
            </div>
        </div>
    </section>
</template>

<script>
export default {
    name: "chatlist",
    data() {
        return {
            isSend: true,
            iv: "",
            showSelBox: 0,
            content: "",
            userId: "",
            conversationId: "",
            parentMessageId: "",
            records: [],
        };
    },
    methods: {
        Play(text) {
            if (navigator.userAgent.indexOf("Edg") > -1) {
                this.cnStore.vociceOpen && this.cnSpeech.speak({
                    text: text
                }).then(() => { })
            }
        },
        //发送消息
        s: function () {
            var _this = this;
            if (!_this.isSend) return;
            if (_this.content == "") return;
            _this.records.push({
                type: 1,
                time: _this.cnUtil.formatDate.format(new Date(), "yyyy-MM-dd hh:mm:ss"),
                name: "游客",
                content: _this.content,
            });
            _this.sendMsg(_this.content);
            _this.scrollToBottom();
        },
        clearMsg() {
            var _this = this;
            _this.content = "";
            setTimeout(() => {
                _this.$refs.input.dispatchEvent(new Event('change', { target: _this.$refs.input }));
            }, 100);
        },
        sendMsg(content) {
            var _this = this;
            if (!_this.isSend) return;
            _this.isSend = false;
            let serverUrl = "https://www.cnbbx.com/api/chat-process"; //serverUrl = "http://www.v.cnbbx.com:8000/api/chat-process";
            let Toast = _this.cnToast;
            Toast.show('疯狂计算中', {
                iconClass: 'chatGPT icon-spinner fa-spin',
                duration: 120000,
            })
            _this.clearMsg();
            _this.cnAxios.post(serverUrl, {
                prompt: content,
                options: {
                    parentMessageId: _this.parentMessageId
                }
            }, {
                headers: {
                    'Content-Type': 'application/json'
                },
                responseType: 'text',
                onDownloadProgress: (progressEvent) => {
                }
            }).then((res) => {
                if (res.status === 200) {
                    Toast.close();
                    _this.records.push({
                        type: 2,
                        time: _this.cnUtil.formatDate.format(new Date(), "yyyy-MM-dd hh:mm:ss"),
                        name: "chatGPT",
                        content: "思考中...",
                    });
                    let msgArr = res.data.split("\n");
                    let jsonObj = JSON.parse(msgArr[msgArr.length - 2]);
                    let message = jsonObj.text ?? jsonObj.message;
                    _this.parentMessageId = jsonObj.parentMessageId;
                    _this.storeParentMessageId(jsonObj.parentMessageId);
                    _this.Play(message);
                    let content = "";
                    let index = 0;
                    let intervalId = setInterval(() => {
                        if (index < message.length) {
                            content += message.slice(index, index + 1);
                            _this.records[_this.records.length - 1].content = content + "|";
                            index++;
                            _this.scrollToBottom();
                        } else {
                            _this.records[_this.records.length - 1].content = _this.records[_this.records.length - 1].content.slice(0, -1);
                            clearInterval(intervalId);
                            hljs.highlightAll({
                                languageDetectRe: /<\?php[\s\S]+?\?>|<%[\s\S]+?%>|<script[\s\S]+?<\/script>|<style[\s\S]+?<\/style>|<!\[CDATA\[[\s\S]+?\]\]>|^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$|^\w+\b/,
                                languages: ['python', 'java'],
                                language: 'python'
                            });
                            _this.storeRecords(_this.records);
                            _this.isSend = true;
                        }
                    }, 100);
                }
                else {
                    Toast.close();
                    _this.sendMsg(content);
                }
            }).catch(function (error) {
                Toast.close();
                Toast.error(error.message);
                new Function("error", "console.warn(error);")(error);
            });
        },
        escapeVue(str) {
            if (!str) {
                return '';
            }
            return str.replace(/[<>"'&]/g, function (match) {
                switch (match) {
                    case '<':
                        return '&lt;';
                    case '>':
                        return '&gt;';
                    case '"':
                        return '&quot;';
                    case "'":
                        return '&#39;';
                    case '&':
                        return '&amp;';
                    default:
                        return match;
                }
            });
        },
        e(data) {
            let encryptData = this.cnCryptoJS.AES.encrypt(data, this.cnk, {
                mode: this.cnCryptoJS.mode.CBC,
                iv: this.iv,
                padding: this.cnCryptoJS.pad.Pkcs7
            });
            return encryptData.toString()
        },
        d(data) {
            let encryptData = this.cnCryptoJS.AES.decrypt(data, this.cnk, {
                mode: this.cnCryptoJS.mode.CBC,
                iv: this.iv,
                padding: this.cnCryptoJS.pad.Pkcs7
            });
            return encryptData.toString(this.cnCryptoJS.enc.Utf8);
        },
        //聚焦输入框
        focusTxtContent: function () {
            document.querySelector("#txtContent").focus();
        },
        //滚动条滚动到底部
        scrollToBottom: function () {
            setTimeout(function () {
                var chatlist = document.getElementsByClassName("chatlist")[0];
                chatlist.scrollTop = chatlist.scrollHeight;
            }, 300);
        },
        // 存储聊天记录到本地
        storeRecords(records) {
            localStorage.setItem("records", JSON.stringify(records));
        },
        // 加载所有聊天记录，并显示在页面上
        loadRecords() {
            var recordList = JSON.parse(localStorage.getItem("records")) || [];
            if (recordList.length === 0) {
                recordList.push({
                    type: 2,
                    time: this.cnUtil.formatDate.format(new Date(), "yyyy-MM-dd hh:mm:ss"),
                    name: "chatGPT",
                    content:
                        "欢迎使用免费chatGPT Plus，本版本通过第三方通讯的，切勿输入个人重要信息。",
                });
                this.storeRecords(recordList);
            }
            this.records = recordList;
        },
        // 删除指定索引的聊天记录
        deleteRecord(indexToDelete) {
            this.records.splice(indexToDelete, 1);
            localStorage.setItem("records", JSON.stringify(this.records));
        },
        // 存储会话 ID 到本地
        storeConversationId(conversationId) {
            localStorage.setItem("conversationId", conversationId);
        },
        // 加载会话 ID，并创建新的会话 ID 如果不存在
        loadConversation() {
            var storedConversationId = localStorage.getItem("conversationId");
            if (!storedConversationId) {
                storedConversationId = this.cnCryptoJS.AES.encrypt(
                    new Date().getTime().toString(),
                    "b" + "b" + "b"
                ).toString();
                this.storeConversationId(storedConversationId);
            }
            this.conversationId = storedConversationId;
        },
        // 存储前一条会话ID 到本地
        storeParentMessageId(parentMessageId) {
            localStorage.setItem("parentMessageId", parentMessageId);
        },
        // 加载前一条会话 ID
        loadParentMessageId() {
            var storedParentMessageId = localStorage.getItem("parentMessageId");
            if (storedParentMessageId) {
                this.parentMessageId = storedParentMessageId;
            }
        },
    },
    mounted: function () {
        // 加载所有聊天记录，并显示在页面上
        this.loadRecords();
        this.iv = this.cnCryptoJS.enc.Utf8.parse("\x62\x62\x63" + "\x62" + "\x62\x62" + 'x' + "\x62" + "\x62" + "\x62" + "\x63" + "\x62" + "\x62\x62" + 'x' + "\x62");
        this.scrollToBottom();
        this.content += this.$refs.input.value;
        this.focusTxtContent();
        this.userId = "#/chat/" + Date.now();
        this.loadConversation();
        this.loadParentMessageId();
    },
};
</script>

<style>
pre {
    white-space: pre-wrap;
}

pre code.hljs {
    padding: 0;
    background: transparent;
    font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
        Microsoft YaHei, SimSun, sans-serif;
}

.chatlist {
    position: absolute;
    top: 60px;
    bottom: 48px;
    left: 0px;
    right: 0px;
    overflow-y: scroll;
    overflow-x: hidden;
    padding: 10px;
}

.chatlist-bottom {
    bottom: 48px;
}

.chatlist-bottom-collapse {
    bottom: 198px;
}

.chatlist ul {
    min-height: 300px;
}

.chatlist ul .chat-mine {
    text-align: right;
    padding-left: 0;
    padding-right: 60px;
}

.chatlist ul li {
    position: relative;
    /*font-size: 0;*/
    margin-bottom: 10px;
    padding-left: 60px;
    min-height: 68px;
}

.chat-mine .chat-user {
    left: auto;
    right: 3px;
}

.chat-user {
    position: absolute;
    left: 3px;
}

.chat-text,
.chat-user {
    display: inline-block;
    vertical-align: top;
    /*font-size: 14px;*/
}

.chat-user img {
    width: 40px;
    height: 40px;
    border-radius: 100%;
}

.time {
    width: 100%;
}

cite {
    left: auto;
    right: 60px;
    text-align: right;
}

cite {
    font-style: normal;
    line-height: 24px;
    font-size: 12px;
    white-space: nowrap;
    color: #999;
    text-align: left;
}

cite i {
    font-style: normal;
    padding-left: 5px;
    padding-right: 5px;
    font-size: 12px;
}

.chat-mine .chat-text {
    margin-left: 0;
    text-align: left;
    background-color: #33df83;
    color: #fff;
}

.chat-text {
    position: relative;
    line-height: 22px;
    /*margin-top: 25px;*/
    padding: 10px 15px;
    background-color: #eee;
    border-radius: 3px;
    color: #333;
    word-break: break-all;
    max-width: 462px\9;
}

.chat-text,
.chat-user {
    display: inline-block;
    vertical-align: top;
    font-size: 14px;
}

.chat-text img {
    max-width: 100%;
    vertical-align: middle;
}

.chat-user {
    position: absolute;
    left: 3px;
}

.chat-text:after {
    content: "";
    position: absolute;
    left: -10px;
    top: 15px;
    width: 0;
    height: 0;
    border-style: solid dashed dashed;
    border-color: #eee transparent transparent;
    overflow: hidden;
    border-width: 10px;
}

.chat-mine .chat-text:after {
    left: auto;
    right: -10px;
    border-top-color: #33df83;
}

.foot {
    width: 100%;
    min-height: 48px;
    position: fixed;
    bottom: 0px;
    left: 0px;
    right: 0px;
    background-color: #f8f8f8;
}

.foot .con {
    position: absolute;
    top: 10px;
    left: 10px;
    right: 80px;
}

.foot .coc {
    position: absolute;
    right: 85px;
}

.btn {
    display: inline-block;
    vertical-align: top;
    font-size: 14px;
    line-height: 32px;
    margin-left: 5px;
    padding: 0 6px;
    background-color: #33df83;
    color: #fff;
    border-radius: 3px;
}

.btn-send {
    position: absolute;
    right: 10px;
    top: 8px;
}
</style>
